package com.zzh.partnersys.ai.util;

import com.zzh.partnersys.common.constant.redis.ChatRedisConstant;
import com.zzh.partnersys.common.enums.ChatTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import jakarta.annotation.Resource;

/**
 * Redis序列号生成工具类
 * 用于生成聊天消息的序列号
 *
 * @author zzh
 */
@Slf4j
@Component
public class RedisSequenceUtil {

    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 生成聊天序列号
     * Key格式: partner:chat:sequence:{chatType}_{targetId}
     * 使用Redis INCR命令生成自增序列号
     *
     * @param chatType 聊天类型（1-单聊，2-群聊）
     * @param targetId 目标ID（单聊=chat_session.id，群聊=chat_group.id）
     * @return 序列号（从1开始自增）
     */
    public Long generateSequence(Integer chatType, Long targetId) {
        if (chatType == null || targetId == null || targetId <= 0) {
            log.error("生成序列号失败：参数错误，chatType: {}, targetId: {}", chatType, targetId);
            throw new IllegalArgumentException("聊天类型和目标ID不能为空");
        }

        // 验证聊天类型是否有效
        ChatTypeEnum chatTypeEnum = ChatTypeEnum.getByCode(chatType);
        if (chatTypeEnum == null) {
            log.error("生成序列号失败：无效的聊天类型，chatType: {}", chatType);
            throw new IllegalArgumentException("无效的聊天类型: " + chatType);
        }

        // 构建Redis Key: partner:chat:sequence:{chatType}_{targetId}
        String key = ChatRedisConstant.buildChatSequenceKey(chatType, targetId);

        try {
            // 使用INCR命令生成自增序列号
            Long sequence = redisTemplate.opsForValue().increment(key);
            if (sequence == null) {
                log.error("生成序列号失败：Redis返回null，key: {}", key);
                throw new RuntimeException("生成序列号失败");
            }
            log.debug("生成序列号成功，key: {}, sequence: {}", key, sequence);
            return sequence;
        } catch (Exception e) {
            log.error("生成序列号失败，key: {}", key, e);
            throw new RuntimeException("生成序列号失败: " + e.getMessage(), e);
        }
    }

    /**
     * 生成聊天序列号（使用枚举）
     *
     * @param chatTypeEnum 聊天类型枚举
     * @param targetId     目标ID（单聊=chat_session.id，群聊=chat_group.id）
     * @return 序列号（从1开始自增）
     */
    public Long generateSequence(ChatTypeEnum chatTypeEnum, Long targetId) {
        if (chatTypeEnum == null) {
            throw new IllegalArgumentException("聊天类型枚举不能为空");
        }
        return generateSequence(chatTypeEnum.getCode(), targetId);
    }

    /**
     * 获取当前序列号（不递增）
     *
     * @param chatType 聊天类型（1-单聊，2-群聊）
     * @param targetId 目标ID（单聊=chat_session.id，群聊=chat_group.id）
     * @return 当前序列号，如果不存在返回0
     */
    public Long getCurrentSequence(Integer chatType, Long targetId) {
        if (chatType == null || targetId == null || targetId <= 0) {
            log.error("获取序列号失败：参数错误，chatType: {}, targetId: {}", chatType, targetId);
            return 0L;
        }

        String key = ChatRedisConstant.buildChatSequenceKey(chatType, targetId);

        try {
            Object value = redisTemplate.opsForValue().get(key);
            if (value == null) {
                return 0L;
            }
            if (value instanceof Number) {
                return ((Number) value).longValue();
            }
            // 尝试转换为Long
            return Long.parseLong(value.toString());
        } catch (Exception e) {
            log.error("获取序列号失败，key: {}", key, e);
            return 0L;
        }
    }

    /**
     * 重置序列号（删除Key）
     *
     * @param chatType 聊天类型（1-单聊，2-群聊）
     * @param targetId 目标ID（单聊=chat_session.id，群聊=chat_group.id）
     * @return 是否删除成功
     */
    public boolean resetSequence(Integer chatType, Long targetId) {
        if (chatType == null || targetId == null || targetId <= 0) {
            log.error("重置序列号失败：参数错误，chatType: {}, targetId: {}", chatType, targetId);
            return false;
        }

        String key = ChatRedisConstant.buildChatSequenceKey(chatType, targetId);

        try {
            Boolean deleted = redisTemplate.delete(key);
            log.debug("重置序列号，key: {}, deleted: {}", key, deleted);
            return Boolean.TRUE.equals(deleted);
        } catch (Exception e) {
            log.error("重置序列号失败，key: {}", key, e);
            return false;
        }
    }
}

